﻿#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>

//teacher 类 老师类
//student 类 学生类
//下课后 老师触发一个信号 饿了 学生响应信号 请客吃饭

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创造一个老师对象
    this->zt = new Teacher(this);

    //创造一个学生对象
    this->st = new Student(this);

//    //老师饿了 学生请客链接
//    connect(zt,&Teacher::hungry,st,&Student::treat);  //这里不用加函数括号

//    //调用下课函数 注意要先创造链接再触发信号
//    classIsOver();

    //新的连接中要让系统能够区分调用带参数的还是不带参数的
    //可以用 函数指针 来指向 带参数的信号和槽
    //注意 函数指针 的使用格式
    void(Teacher:: *teachersignal)(QString) = &Teacher::hungry;  //qstring代表参数类型，确定指的谁，注意右边没有括号
    void(Student:: *studentslot)(QString) = &Student::treat;     //qstring代表参数类型，确定指的谁，注意右边没有括号
    connect(zt,teachersignal,st,studentslot);                    //建立连接
    //classIsOver();

    //点击 下课的按钮，触发下课
    QPushButton * btn = new QPushButton("下课",this);
    this->resize(600,400);

    //点击按钮 触发下课
    connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);

    //无参信号和槽链接
    void(Teacher:: *teachersignal2)(void) = &Teacher::hungry;  
    void(Student:: *studentslot2)(void) = &Student::treat;     
    connect(zt,teachersignal2,st,studentslot2);
    
    //信号连接信号，点击下课按钮触发老师饿了信号
    connect(btn, &QPushButton::clicked, zt , teachersignal2);

    //断开信号disconnect，参数直接复制connect中的参数就行
    disconnect(zt,teachersignal2,st,studentslot2);


    //lambda表达式
    //中括号内空表示没有使用任何函数对象参数
    //[=]可以使用作用范围内所有局部变量，值传递
    //[&]可以使用作用范围内所有局部变量，引用传递
    //[btn]值传递btn，默认传递进来为const类型的拷贝，可用mutable修改拷贝
    //[&btn]引用传递btn
    //[=，&btn]其他值传递，btn引用传递
    //声明格式：[](){};
    //调用格式：[](){}();
    [=]()
    {
        btn->setText("aaaa");
    }();

//    //lambda表达式使用方法
//    QPushButton * myBtn = new QPushButton (this);
//    QPushButton * myBtn2 = new QPushButton (this);
//    myBtn->move(0,100);
//    myBtn2->move(100,100);
//    int m = 10;
//    //注意将lambda表达式作为槽使用的格式
//    //【m】并不会改变m的值，改变的是形参，形参默认为const类型，需要用mutable才能修改形参
//    connect(myBtn,&QPushButton::clicked,this,[m]()mutable{m=100+10;qDebug()<<m;});
//    connect(myBtn2,&QPushButton::clicked,this,[=](){qDebug()<<m;});

    //lambda表达式返回值设定
    int ret = []()->int{return 1000;}();
    qDebug()<<"ret = "<<ret;

    //利用lambda表达式实现 点击按钮 关闭窗口
    QPushButton * btn2 = new QPushButton("close",this);
    btn2->move(200,0);
    //等价于：connect(btn,&QPushButton::clicked,this,&Widget::close);
    //优点：lambda表达式是函数，可以同时执行多条语句
    //槽函数是lambda表达式时，如果信号接收者是this可以省略
    connect(btn2,&QPushButton::clicked,[=](){
        this->close();
        classIsOver();
    });



}

void Widget::classIsOver()
{
    //下课函数，调用后触发 老师饿了的信号 关键字emit发出
    emit zt->hungry();  //注意这里要加函数括号
    emit zt->hungry("宫保鸡丁");

}


Widget::~Widget()
{
    delete ui;
}
